﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace DarwinIsDead.Traits
{
    public class Arm : Trait
    {
        Player player;
        private Texture2D sprite;
        private SpriteFont debugFont;

        private List<Bullet> bullets;
        private int currentBullet;

        private float fireTime;
        private float fireCounter;

        private int baseDamage;
        private float baseSpeed;
        private float baseRange;

        private float attackSpeed;
        private float attackRange;

        // Ctor
        public Arm(Zombie owner, World world = null)
            : base(owner, world)
        {
            // Apply any changes to the owning Zombie that doesn't involve
            // accessing other Trait

            bullets = new List<Bullet>();
            baseDamage = 1;
            baseSpeed = 1f;
            baseRange = 500f;

            currentBullet = 0;

            fireTime = 0.125f;

            attackSpeed = baseSpeed;  // performs close range attack every 1s
            attackRange = baseRange;  // attack range

            // Load sound, graphics, etc.
            sprite = World.Game.Content.Load<Texture2D>("Sprites\\Traits\\sprArms");
            debugFont = World.Game.Content.Load<SpriteFont>("Fonts\\Courier New");
        }

        public override void Initialize() {
            Owner.HitBox.Width += 20;   // Add some dimension to the zombie's hitbox
            Owner.HitBox.Height += 20;

            List<Entity> players = World.GetEntities<Player>();
            if (players.Count > 0)
            {
                player = (Player)players[0];
            }

            for (int i = 0; i < 10; i++)
            {
                Bullet bullet = new Bullets.Linear(World, 1, 800f, 1f, false);
                bullet.NotifyDamage = Owner.AddDamage;
                bullets.Add(bullet);
                World.AddEntity(bullet);
            }

            Level = 1;
        }

        public override object Clone() {
            Arm ret = new Arm(Owner, World);
            return ret;
        }

        public override void Dispose()
        {
            // Remove all bullets from the world, so we're not wasting
            // cycles checking for collisions against dead objects
            foreach (Bullet bullet in bullets)
            {
                World.RemoveEntity(bullet);
            }
        }

        protected override void AdjustLevel(int level)
        {
            // Apply any changes that occur with leveling up.
            attackRange = level + baseRange;

            foreach (Bullet bullet in bullets)
            {
                bullet.Damage = level * baseDamage;
            }
        }

        protected override void InternalUpdate(GameTime gameTime)
        {
            // Our delta time (time between game updates) in seconds.
            // You can use whatever format you want, but this is my preferred.
            float dt = gameTime.ElapsedGameTime.Milliseconds / 1000f;

            // Move to player and hug the bastard
            if (player != null)
            {
                // Get the distance between the zombie and the player
                float dpx = player.Position.X - Owner.Position.X;
                float dpy = player.Position.Y - Owner.Position.Y;
                float dir = (float)Math.Atan2(dpy, dpx);
                double dist = Math.Abs(dpx + dpy);

                if (dist <= attackRange) {
                  //if (Math.Abs(dpx) <= attackRange && Math.Abs(dpy) <= attackRange){
                    fireCounter += dt;  // Wait a bit between shots
                    if (fireCounter > fireTime)
                    {
                        fireCounter = 0f;
                        // Fire a bullet
                        if (!bullets[currentBullet].Active)
                        {
                            bullets[currentBullet].Fire(Owner.Position, dir);
                        }
                        currentBullet = (currentBullet + 1) % bullets.Count;
                    }
                }

            }
        }

        protected override void InternalDraw(SpriteBatch spriteBatch, Color color)
        {
            Vector2 drawPosition = new Vector2(Owner.Position.X, Owner.Position.Y);
            drawPosition.X -= 20f;  // Draw the arms a little infront of the body
            drawPosition.Y -= 10f;

            // Draw the damn thing
            spriteBatch.Draw(sprite, drawPosition, color);

            //TODO: Move the arms like it's attacking
        }
    }
}
